package com.pic.mgt;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.pic.mgt.cli.CommandLineArgParser;
import com.pic.mgt.config.ConfigBean;
import com.pic.mgt.config.ConfigurationException;
import com.pic.mgt.initials.InitialBeansExecuter;
import com.pic.mgt.initials.InitialOperationException;

/**
 * [系統載入]
 * Launcher 將系載入並做設定檔確認。
 * @author 洪政緯
 *
 */
public abstract class Launcher {
	public static ApplicationContext applicationContext;
	
	protected CommandLineArgParser igalaxyCLI;
	
	protected Launcher(CommandLineArgParser igalaxyCLI) throws SystemLaunchException {
		this.igalaxyCLI = igalaxyCLI;
		
		// (1) 建立 Spring ApplcationContext ------------------------------------
		String[] serviceResources = applicationContextResources();
		applicationContext = 
			new ClassPathXmlApplicationContext(serviceResources);
						
		// (2) 做設定檔內容確認 --------------------------------------------------
		try {
			checkCommonConfiguration();
			checkSpecificConfiguration();
		} catch (ConfigurationException e) {
			// TODO 寫入錯誤 log
			
			// 拋出給呼叫者
			throw new SystemLaunchException("System launch failed.", e);
		}
		
		// (3) 執行系統初始化動作
		try {
			InitialBeansExecuter initialBeansExecuter =
				applicationContext.getBean("commonInitialBeansExecuter",
										   InitialBeansExecuter.class);
			// throws InitialOperationException
			initialBeansExecuter.doInitialization();
		} catch (InitialOperationException e) {
			// 不用寫 log (已經寫)
			
			// 拋出給呼叫者
			throw new SystemLaunchException("System launch failed.", e);
		}
	}
	
	/**
	 * 回傳 Spring Application Context 的設定檔。
	 * @return String 陣列，內的元素是 resource 的檔名(不包含路徑），各
	 * resource 必須是在 classpath 底下。
	 */
	protected abstract String[] applicationContextResources();
	
	/*
	 * 確認設定檔內容是否設定正確。
	 * @throws ConfigurationException
	 */
	private void checkCommonConfiguration() throws ConfigurationException {
		ConfigBean systemConfigBean = 
			this.applicationContext.getBean("systemConfig",
											 SystemConfigBean.class);
		// TODO 檢查  SystemConfigBean 格式
	}
	
	/**
	 * 確認設定檔內容是否設定正確。
	 * @throws ConfigurationException
	 */
	protected abstract void checkSpecificConfiguration()
										throws ConfigurationException;
	
}
